# uncompyle6 version 3.2.3
# Python bytecode 3.6 (3379)
# Decompiled from: Python 3.6.8 |Anaconda custom (64-bit)| (default, Feb 21 2019, 18:30:04) [MSC v.1916 64 bit (AMD64)]
# Embedded file name: api\handlers\frontend\excluded_hours.py
import logging, datetime, uuid
from dateutil.tz import tzlocal
from sqlalchemy import select as sql_select
from sqlalchemy import func as sql_func
from sqlalchemy.dialects.postgresql import JSONB as TYPE_JSONB
from sqlalchemy import type_coerce
import sqlalchemy.exc
from api.classes.frontend.auto import *
from db import Connection
from db.data.users import get_owner_id, require_at_least_tech_admin_with_access_all
from db.tables.targets_configurations import (
    TargetConfigurationRow,
    TargetConfigurationTable,
)
from api.handlers.frontend import FrontendResourceHandler
from db.tables.excluded_hours import ExcludedHoursRow, ExcludedHoursTable
from db.tables.system_config import SystemConfigRow, SystemConfigTable
from server.http_responses.http_status_codes import Http201, Http204
from server.http_responses.http_errors import Http404, Http409

logger = logging.getLogger("api.ExcludedHours")


class ExcludedHours(FrontendResourceHandler):
    def get_excluded_hours_profiles(self, **_):
        owner_id = get_owner_id(self.request_user)
        qc = sql_select((sql_func.count(ExcludedHoursRow.excluded_hours_id),)).where(
            ExcludedHoursRow.owner_id == owner_id
        )
        ql = (
            sql_select((ExcludedHoursRow,))
            .where(ExcludedHoursRow.owner_id == owner_id)
            .where(ExcludedHoursRow.deleted_at.is_(None))
        )
        result = ClsExcludedHoursProfilesList(values=[])
        with Connection(self.current_shard_name) as (db):
            c = db.execute(qc).scalar()
            if not c:
                ltz = tzlocal()
                lo = ltz.utcoffset(datetime.datetime.now(ltz))
                time_offset = int(lo.total_seconds() / 60)
                data = dict(
                    excluded_hours_id=str(uuid.uuid4()),
                    owner_id=owner_id,
                    name="Allows scans from 9am to 5pm",
                    time_offset=time_offset,
                    data={
                        "exclusion_matrix": [
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                        ]
                    },
                )
                q = ExcludedHoursTable.insert().values(**data)
                db.execute(q)
                data = dict(
                    excluded_hours_id=str(uuid.uuid4()),
                    owner_id=owner_id,
                    name="No weekends",
                    time_offset=time_offset,
                    data={
                        "exclusion_matrix": [
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                        ]
                    },
                )
                q = ExcludedHoursTable.insert().values(**data)
                db.execute(q)
                data = dict(
                    excluded_hours_id=str(uuid.uuid4()),
                    owner_id=owner_id,
                    name="Except working hours",
                    time_offset=time_offset,
                    data={
                        "exclusion_matrix": [
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            True,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                            False,
                        ]
                    },
                )
                q = ExcludedHoursTable.insert().values(**data)
                db.execute(q)
            for entry in db.execute(ql).fetchall():
                result.values.append(
                    ClsExcludedHoursProfile(
                        name=entry.name,
                        excluded_hours_id=entry.excluded_hours_id,
                        time_offset=entry.time_offset,
                        exclusion_matrix=entry.data["exclusion_matrix"],
                    )
                )

        return result

    def get_excluded_hours_profile(self, excluded_hours_id, **_):
        owner_id = get_owner_id(self.request_user)
        q = (
            sql_select((ExcludedHoursRow,))
            .where(ExcludedHoursRow.owner_id == owner_id)
            .where(ExcludedHoursRow.excluded_hours_id == excluded_hours_id)
            .where(ExcludedHoursRow.deleted_at.is_(None))
        )
        with Connection(self.current_shard_name) as (db):
            entry = db.execute(q).fetchone()
            if not entry:
                raise Http404()
            return ClsExcludedHoursProfile(
                name=entry.name,
                excluded_hours_id=entry.excluded_hours_id,
                time_offset=entry.time_offset,
                exclusion_matrix=entry.data["exclusion_matrix"],
            )

    def create_excluded_hours_profile(self, body, **_):
        owner_id = get_owner_id(self.request_user)
        require_at_least_tech_admin_with_access_all(self.request_user)
        excluded_hours_entry = ClsExcludedHoursProfile(**body)
        excluded_hours_id = str(uuid.uuid4())
        values = dict(
            excluded_hours_id=excluded_hours_id,
            owner_id=owner_id,
            creator_id=self.request_user["user_id"],
            name=excluded_hours_entry.name,
            time_offset=excluded_hours_entry.time_offset,
            data=dict(exclusion_matrix=excluded_hours_entry.exclusion_matrix),
        )
        q = (ExcludedHoursTable.insert().values(**values)).returning(
            ExcludedHoursRow.excluded_hours_id
        )
        with Connection(self.current_shard_name) as (db):
            excluded_hours_id = None
            try:
                excluded_hours_id = db.execute(q).scalar()
            except sqlalchemy.exc.IntegrityError as e:
                if "uix_excluded_targets_name" in str(e):
                    raise Http409("Duplicate profile name")

            excluded_hours_entry.excluded_hours_id = excluded_hours_id
            return Http201(
                location=self.base_path
                + "/excluded_hours_profiles/"
                + excluded_hours_id,
                body=excluded_hours_entry,
            )

    def modify_excluded_hours_profile(self, excluded_hours_id, body, **_):
        owner_id = get_owner_id(self.request_user)
        require_at_least_tech_admin_with_access_all(self.request_user)
        values = dict()
        excluded_hours_entry = ClsExcludedHoursProfile(**body)
        if excluded_hours_entry.get("name"):
            values["name"] = excluded_hours_entry.name
        if excluded_hours_entry.get("time_offset") is not None:
            values["time_offset"] = excluded_hours_entry.time_offset
        if excluded_hours_entry.get("exclusion_matrix") is not None:
            values["data"] = dict(
                exclusion_matrix=excluded_hours_entry.exclusion_matrix
            )
        if not values:
            return Http204()
        else:
            q = (
                (ExcludedHoursTable.update(values=values))
                .where(ExcludedHoursRow.owner_id == owner_id)
                .where(ExcludedHoursRow.excluded_hours_id == excluded_hours_id)
                .where(ExcludedHoursRow.deleted_at.is_(None))
                .returning(ExcludedHoursRow.excluded_hours_id)
            )
            with Connection(self.current_shard_name) as (db):
                result = None
                try:
                    result = db.execute(q).scalar()
                except sqlalchemy.exc.IntegrityError as e:
                    if "uix_excluded_targets_name" in str(e):
                        raise Http409("Duplicate profile name")

                if not result:
                    raise Http404()
            return Http204()

    def remove_excluded_hours_profile(self, excluded_hours_id, **_):
        owner_id = get_owner_id(self.request_user)
        require_at_least_tech_admin_with_access_all(self.request_user)
        qe = (
            (
                ExcludedHoursTable.update(
                    values=dict(deleted_at=datetime.datetime.now(tzlocal()))
                )
            )
            .where(ExcludedHoursRow.owner_id == owner_id)
            .where(ExcludedHoursRow.excluded_hours_id == excluded_hours_id)
            .where(ExcludedHoursRow.deleted_at.is_(None))
            .returning(ExcludedHoursRow.excluded_hours_id)
        )
        qt = (
            TargetConfigurationTable.delete()
            .where(TargetConfigurationRow.name == "excluded_hours_id")
            .where(
                TargetConfigurationRow.value
                == type_coerce(str(uuid.UUID(excluded_hours_id)), TYPE_JSONB)
            )
        )
        qs = (
            SystemConfigTable.delete()
            .where(SystemConfigRow.name == "excluded_hours_id")
            .where(
                SystemConfigRow.value
                == type_coerce(str(uuid.UUID(excluded_hours_id)), TYPE_JSONB)
            )
        )
        with Connection(self.current_shard_name) as (db):
            if not db.execute(qe).scalar():
                raise Http404()
            db.execute(qt)
            db.execute(qs)
        return Http204()
